home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
utils
/
inttools
/
intview.asm
< prev
next >
Wrap
Assembly Source File
|
1995-04-20
|
10KB
|
350 lines
;
; Program to print the segment, and offset info of an interrupt handler.
; Version One, Steve Kemp '95
;
; Operation, either
;
; INTVIEW [/?] - Print info
; INTVIEW /A - Print all interrupt handlers addresses
; INTVIEW xx - xx = Decimal int. number to print location of
; INTVIEW xxh - xx = Hexidecimal int. number to print location of.
;
;
;
; e.g. Find the location of the int 13h handler, either use:
;
; INTVIEW 13h, or INTVIEW 19 (13h=19 decimal)
;
parser:
mov SI,80h
parse_loop:
inc SI ; Get ready for next character
mov Dl,[SI] ; Get character from command tail
cmp Dl,'/' ; Switch??
jz found_slash ; If so goto switch routine
cmp Dl,0Dh ; End of tail??
jnz parse_loop ; If not repeat
cmp SI,81h ; Still at start of tail??
jnz number_entered ; If not continue
mov DX,info_message ; Else queue up error message
call print_string ; Print it
jmp return2DOS ; and return to DOS
number_entered:
call calculate_number ; Calculate number on command line
; Store it in int_number
mov AX,[int_number] ; Get the number calculated
cmp AX,255 ; Is it bigger than 255??
jle not_too_big ; If not continue
mov DX,too_big ; Queue up 'Too big message'
call print_string ; Print it
jmp return2DOS ; Stop
not_too_big:
call print_initial ; Print the int number selected
call display_address ; Now print the actual segment:offset
jmp return2DOS ; Return to DOS
found_slash:
inc SI ; Point to next letter
mov Dl,[SI] ; Get it into Dl
cmp Dl,'?' ; ? ?? If so print info about program
jz info
or Dl,32 ; Convert to ASCII lowercase
cmp Dl,'a'
jz do_all ; /a ?? If so go setup printing all
push DX ; Otherwise invalid switch. Save it
mov DX,invalid_switch ; Print invalid switch message
call print_string ; Here
pop DX ; Get back saved letter
add Dl,'A'-'a' ; Print uppercase version of letter
mov Ah,02 ; Print a single character
int 21h ; Now!
return2DOS:
mov Ah,4ch ; Return to DOS
int 21h ; There!
info:
mov DX,info_message ; Point to info. string
call print_string ; Print the string
jmp return2DOS ; finished!
;
; Pleasant routine to print out all the interrupts, one after the other
; by looping and increasing the int. number to display on each iteration
;
do_all:
mov CX,00 ; Counter
do_all_loop:
push CX ; Save counter on the stack
mov [int_number],CX ; Adjust the number to print
call print_initial ; print the initial message
call display_address ; Now print the handlers address
call print_crlf ; Print a CR, LF
pop CX
inc Cl
cmp Cl,00
jnz do_all_loop
jmp return2DOS
;
; The following routine determines whether the input number is hex or
; decimal, and calculates it, storing the result into the buffer 'int_number'
;
calculate_number:
mov SI,82h ; Number is first parameter on Command
mov DI,ascii_buffer ; Put a copy of it into the temporary
movsw ; buffer
movsb
dec SI ; Point to buffer+1
mov CX,2 ; Three bytes long max
hex_or_dec:
mov Dl,[si] ; Get a letter
or Dl,32
cmp dl,"h" ; Is it a hex number marker??
jz hex_number
inc SI
loop hex_or_dec ; Repeat
decimal_number:
mov CX,0003
mov AX,0000
mov SI,ascii_buffer
test_validity:
mov Dl,[SI]
cmp Dl,'0'-1
jle end_of_number
cmp Dl,'9'+1
jge end_of_number
inc AX
inc SI
loop test_validity
end_of_number:
mov SI,ascii_buffer ; Reset pointer
mov Dh,00h ; Blank high byte of Dh
cmp AX,0001
jz one_byte
cmp AX,0002
jz two_byte
cmp AX,0003
jz three_byte
ret
one_byte: ; We have a one ASCII-digit number
mov Dl,[SI] ; Get the digit
sub Dl,'0' ; Convert it.
mov word ptr [int_number],DX ; Dh=00 already
ret
two_byte:
mov Dl,[SI] ; Get the most significant number
sub Dl,'0' ; Convert it
mov Al,10 ; Multiply it by ten, high byte =00h
mul DX ; Result in AX
xor DX,DX ; Set DX=0000
inc SI ; Point to next number
mov Dl,[SI] ; Get it.
sub Dl,'0' ; Canvert that
add DX,AX ; Add it to total
mov word ptr [int_number],DX ; Store it in the store
ret ; Return
three_byte:
mov Dl,[Si] ; Get first letter
sub Dl,'0' ; Convert it to 0-9
mov AX,100 ; We want to multiply it by 100
mul DX ; Do it. Returns the result in AX
mov BX,AX ; Save it in BX
inc SI ; Point to next letter
call two_byte ; Proceed as if it were only two digits
add DX,BX ; Add the two digit total to the preserved
mov word ptr [int_number],DX ; BX, and store it in the store
ret ; Return
;
; Hex numbers handled here
;
hex_number:
mov SI,ascii_buffer ; Point to beginning of ASCII buffer
mov Dl,[SI] ; Get a character
inc SI ; Move pointer up by one
mov Dh,[SI] ; Get another character
or Dh,32 ; Conver secong character to lower case
cmp Dh,'h' ; Is it a 'h'
jz one_digit_hex ; If so number is one ASCII-byte long
two_digit_hex: ; Else it MUST be two ASCII-bytes long
cmp Dl,'9'
jle less_than_nine_1 ; Is it a number??
or Dl,32 ; If not its a letter, lowercase it becomes
sub dl,'a'-10-'0' ; Adjust value
less_than_nine_1:
sub Dl,'0' ; Convert it to number 0-15
mov AX,16 ; Get ready to multiply by 16
mov Dh,00
mul DX ; Do it! (Result in AX)
push AX ; Save result on stack
mov Dl,[SI] ; Get next digit
call one_digit_hex ; Treat it as a one digit number
pop AX ; Restore the value that we saved
add AX,DX ; Add high+low results
mov [int_number],AX ; Finally store the result in the bufffer
ret ; Finished (Phew!)
one_digit_hex:
cmp Dl,'9' ; Is it a digit??
jle less_than_nine_2 ; If so goto digit routine
or dl,32 ; Convert letter to lower case
sub Dl,'a'-'9'-1 ; Adjust it
less_than_nine_2:
sub Dl,'0' ; Convert it to a number 0-15
mov Dh,00 ; Blank out high byte
mov [int_number],DX ; Store in the buffer
ret ; Return
print_initial:
mov DX,initial_message ; Queue up message
call print_string ; Print it
mov AX,[int_number] ; Get the interupt number
mov Ah,Al ; Put it in Ah
call print_hex ; Print out Ah
mov DX,final_message ; Queue up message
call print_string ; Print it
ret ; Return
;
; This routine prints the contents of Ah as a two-byte hex number.
;
print_hex:
mov al,ah
shr ah,1
shr ah,1
shr ah,1
shr ah,1
cmp ah,9
jbe next1
add ah,7
next1:
add ah,'0'
and al,0fh
cmp al,9
jbe next2
add al,7
next2:
add al,'0'
push cx
mov cl,ah
mov ch,al
mov Ah,02
mov Dl,cl
int 21h
mov Ah,02
mov Dl,ch
int 21h
pop cx
ret
;
; This routine actually prints the segment:offset info of the interrupt
; number stored in 'int_number'
;
Display_address:
mov AX,0004 ; Multiply int number by four
mov BX,[int_number] ; Get int. number
mul BX ; Do the multiplication
mov SI,AX ; Set the pointer accordingly
push DS ; Save the data segment
xor AX,AX ; AX=0000
push AX ; Store the zero value on the stack
pop DS ; Data segment=0000
mov AX,[SI] ; Get the offset of the handler
inc SI ; increase pointer
inc SI ; increase pointer to point to the offset
mov BX,[SI] ; Get the offset
pop DS ; Restore data segment
mov word ptr [offset_buffer],AX ; Store the segment
mov word ptr [segment_buffer],BX ; Store the offset
push AX
mov CX,BX
pop BX ; Swap the registers around
mov AX,CX
push BX ; Keep a copy of the offset on the stack
push AX ; And keep the segment
call print_hex ; Print the high byte of the segment
pop AX
mov Ah,Al
call print_hex ; Print the lowbyte of the segment
mov Ah,02 ; Print a single letter
mov Dl,':' ; A seporater
int 21h ; Now!
pop BX ; Restore the offset
push BX ; Save it for later
mov Ah,Bh ; Print the highbyte
call print_hex
pop AX
mov Ah,Al
call print_hex ; Print the low byte
ret ; Return
print_crlf:
mov DX,lfcr ; Point to linefeed, CR
print_string:
mov Ah,09h ; Get ready to output the string addressed
int 21h ; By DX. Do it.
ret ; Return
; **************************************************************************
; * Output Strings and Data area *
; ********************************
invalid_switch:
db "Invalid switch - /","$"
too_big:
db "Interupt number too big!","$"
info_message:
db "INTVIEW Version One - Steven Kemp 1995",0ah,0dh
db 0ah,0dh
db " Usage: INTVIEW [/?] - Show this information",0ah,0dh
db 0ah,0dh
db " INTVIEW xxx[h] - Show the segment:offset information",0ah,0dh
db " of int. number xxx (Assumes decimal)",0ah,0dh
db " - Can overide by the 'h' suffix.",0ah,0dh
db 0ah,0dh
db " INTVIEW /A - Show the info on _all_ the interrupts",0ah,0dh
db "$"
initial_message:
db "Interrupt number ","$"
final_message:
db "h has its handler at ","$"
lfcr:
db 0A,0Dh,"$"
ascii_buffer:
db 00,00,00
int_number:
dw 0000h
offset_buffer:
dw 0000h
segment_buffer:
dw 0000h